<?php
class Delivery_Model_Mapper_Direcciones
	extends Delivery_Model_Mapper_Abstract
{
	CONST MIN_PRESICION = 8;
	
	public function getDbTable()
	{
		return parent::getDbTable( 'Direcciones' );
	}
	
	/**
	 * @param object Delivery_Model_Direccion
	 */
	public function save( $direccion )
	{
		$dbTable = $this->getDbTAble();
		
		if ( $direccion->getId() == null ){
		   
			$rowset = $dbTable->getByAddress( $direccion->calle, $direccion->numero, $direccion->idCiudad, $direccion->barrio);
			
			// asi me aseguro que la calle moldes 3052 sera grabada solo una vez
			if ( empty($rowset) ){
				$direccion->idDireccion = $dbTable->insert( $direccion );
			} else {
				$direccion->idDireccion = $rowset['idDireccion'];
			}	
		} 
	}
	
	/**
	 * @param int idDireccion
	 * @return objeto Delivery_Model_Direccion
	 */
	public function getById( $idDireccion )
	{
		if ( $this->getIdentityMap()->isRegistered( 'Delivery_Model_Direccion', $idDireccion )){
			return $this->getIdentityMap()->get( 'Delivery_Model_Direccion', $idDireccion );
		}
		
		$dbTable= $this->getDbTable();
		$row	= $dbTable->getById( $idDireccion );
		
		if( empty($row) ){
			throw new Delivery_Model_Exception( Delivery_Model_Exception::ADDRESS_NOT_FOUND );
		}
		
		$direccion = $this->_fetch( $row );
		$this->loadCiudad( $direccion );
		return $direccion;		
	}

	public function getByIds( $ids )
	{
		$dbTable= $this->getDbTAble();
		
		$direcciones = $this->_fetchCollection(
			'Direcciones',
			$dbTable->getByIds( $ids )
		);
		
		$this->loadCiudad( $direcciones );
		return $direcciones;
	}
	
	public function getByAddress( $calle, $numero, $ciudad )
	{		
		$dbTable= $this->getDbTable();
		$row = $dbTable->getByAddress( $calle, $numero, $ciudad );
		
		if( empty($row )){
			return null;
		}
					
		$direccion = $this->_fetch( $row );
		$this->loadCiudad( $direccion );
		return $direccion;		
	}
	
	public function search( $string )
	{	
	    $filter = new My_Filter_CityName();
	    $string = $filter->filter( $string );
	    
		$dbTable= $this->getDbTable();			
		$direccion = $dbTable->search(  $string  );
		
		$collection = Delivery_Model_Factory::collection( 'Direcciones' );
		
		if( $direccion ){
		    
		    $collection->append( $this->_fetch( $direccion ));
		    $this->loadCiudad( $collection );
			return $collection;
		}
		
		$geoCoder = new My_GData_GeoCoder();
		$direcciones = $geoCoder->search( $string );
		
		
		$mapper = Delivery_Model_Factory::mapper( 'Ciudades' );
		
		foreach ($direcciones as $direccion){
			
			if ($direccion['presicion'] >= self::MIN_PRESICION ){				
				
				$_Direccion = $this->_fetch( $direccion );

				$ciudad = $mapper->getByNombre( $direccion['ciudad'] );
				
				if ( !$ciudad ){
					$ciudad = new Delivery_Model_Ciudad(
						array(
							'nombre' => $direccion['ciudad'],
							'provincia' => $direccion['provincia']
						)
					);
					$mapper->insert( $ciudad );
				}
				
				$_Direccion->setCiudad( $ciudad );
				$_Direccion->idCiudad = $ciudad->getId();
				
				$this->save( $_Direccion );			
				$collection->append( $_Direccion );
			}
		}	
		
		return $collection;
	}
	
	/**
	 * @return array de ciudades
	 */
	public function ciudades()
	{
	
		$dbTable= $this->getDbTable();
			
		return $dbTable->ciudades();
	}
	
	public function loadCiudad( $direcciones )
	{
		$mapper = Delivery_Model_Factory::mapper('Ciudades');
		
		if ( 	( 	$direcciones instanceof Delivery_Model_Collection_Direcciones ||
					$direcciones instanceof Delivery_Model_Collection_DireccionesCliente 
				)
			 	&& count($direcciones)
			){
		
			$ciudades = $mapper->getByIds( $direcciones->getKeyValues( 'idCiudad', true ) );
			
			
			foreach ( $direcciones as $direccion){
				$direccion->setCiudad(
					$ciudades->offsetGet( $direccion->idCiudad )
				);
			}
			
		}
		
	 	elseif ( $direcciones instanceof Delivery_Model_Direccion){
			
	 		$direcciones->setCiudad(
	 			$mapper->getById( $direcciones->idCiudad )
	 		);
		}
	}
	
	
	
	/**
	 * @param array
	 * @return objeto Delivery_Model_Direccion
	 */
	protected function _fetch( $row )
	{
		$direccion = new Delivery_Model_Direccion( $row );
		
		$this->getIdentityMap()->set( $direccion, $direccion->getId() );
		
		return $direccion;
	}
	
}